function getOffset(el) {
	var sl = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
	var st = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
	var rect = el.getBoundingClientRect();
	return {
		l : rect.left + sl,
		t : rect.top + st,
		w : el.offsetWidth,
		h : el.offsetHeight
	};
};

function extend(target, source) {
    for (var p in source) {
        if (source.hasOwnProperty(p)) {
            target[p] = source[p];
        }
    }    
    return target;
};

function Sign(id, options) {
	this.id = id;
	this.width = 200;
	this.height = 100;
	this.degree = 0;
	this.rect = {
		top : 0,
		left : 0,
		right : 0,
		buttom : 0
	};
	//记录签名所在区域上下左右的值
	var offset = {
		x : 0,
		y : 0
	};
	var ctx = null;
	var canvas = null;
	var ts = new Date();

	var lineStyle = {
		width : 1,
		color : "#5adf20",//绿色
		kind : 0,
		mode : "round",
		isShow : true
	};
	var gridStyle = {
		width : 0.5,
		background:'#000',
		color : "#ddd",
		mode : "round",
		isShow : true,
		sw : 20,
		sh : 20
	};
	var pointStyle = {
		r : 2,
		color : "#5ad120",
		isShow : true,
		isInterpolation : true
	};
		
	var device = {
		deviceName : "",
		deviceModel : "",
		deviceId : "",
		systemType : "",
		systemVersion : ""
	};
	
	var data = {
		date : new Date(),
		rate : 100,
		count : 0,		
		mode : 'x,y,p,t',
		x : [],
		y : [],
		p : [],
		t : []
	};
	//缺省数据类型
	var allPoint = [];
	/*函数功能*/
	this.log = log;
	//写日志
	this.sigtime = sigtime;
	//获取记录时间
	this.getCount = function() {
		return data.count;
	}

	this.clear = clear;
	//清除
	this.drawGrid = drawGrid;
	//绘制表格
	this.redraw = redraw;
	//重绘
	this.interpolation = interpolation;
	//计算差值，返回数据的类型
	this.headString = HeadString;
	//信息数据
	this.dataString = DataString;
	//头部数据
	this.toString = function() {
		return this.headString() + this.dataString()
	};
	this.fmtString = function() {
		return this.headString() + this.interpolation()
	};

	function sigtime() {
		var aYear = ts.getFullYear();
		var aMonth = ts.getMonth() + 1;
		aMonth = (aMonth.toString().length == 1 ? '0' + aMonth : aMonth);
		var aDate = ts.getDate();
		aDate = (aDate.toString().length == 1 ? '0' + aDate : aDate);
		var aHours = ts.getHours();
		aHours = (aHours.toString().length == 1 ? '0' + aHours : aHours);
		var aMin = ts.getMinutes();
		aMin = (aMin.toString().length == 1 ? '0' + aMin : aMin);
		var aSecond = ts.getSeconds();
		aSecond = (aSecond.toString().length == 1 ? '0' + aSecond : aSecond);
		var ts1 = "" + aYear + aMonth + aDate + aHours + aMin + aSecond;
		return ts1;
	};	

	this.resize = function(w, h) {
		canvas.width = w;
		canvas.height = h;
		this.width = w;
		this.height = h;
		ctx.clearRect(0, 0, w, h);
		this.drawGrid();
		//this.draw();
		drawSeg(0);
	}
	
	this.init = function() {
		canvas = document.getElementById(this.id);
		var rect = canvas.getBoundingClientRect();
		offset.x = rect.left;
		offset.y = rect.top;
		var right = rect.right;
		var bottom = rect.bottom;
		this.width = right - offset.x - 0;
		this.height = bottom - offset.y - 0;
		canvas.width = this.width;
		canvas.height = this.height;
		ctx = canvas.getContext("2d");
		ts = new Date();
		canvas.addEventListener("touchstart", touchStart, false);
		canvas.addEventListener("touchmove", touchMove, false);
		canvas.addEventListener("touchend", touchEnd, false);		
		this.drawGrid();
	};

	this.setDevice = function(_device) {
		device.deviceName = _device.deviceName || "";
		device.deviceModel = _device.deviceModel || "";
		device.deviceId = _device.deviceId || "";
		device.systemType = _device.systemType || "";
		device.systemVersion = _device.systemVersion || "";
	}
	
	function HeadString() {
		var str = "";
		str += "Sample Rate=" + "0\r\n";
		str += "Sample Length=" + data.count + "\r\n";
		str += "Verison=4.0\r\n";
		str += "Deveice=" + device.deviceName + ",";
		str += device.deviceModel + ",";
		str += device.deviceId + ",";
		str += device.systemType + ",";
		str += device.systemVersion + "\r\n";
		str += "Degree=" + this.degree + "\r\n";
		str += "Time=" + this.sigtime() + "\r\n";
		str += "Mark=x,y,p,t\r\n";
		return str;
	};

	function DataString() {
		var str = "";
		var px = data.x;
		var py = data.y;
		var pp = data.p;
		var pt = data.t;
		var count = px.length;
		if (count <= 0)
			return str;
		this.rect.left = px[0];
		this.rect.right = px[0];
		this.rect.top = py[0];
		this.rect.buttom = py[0];

		for (var i = 0; i < count; i++) {
			str += px[i].toFixed(2) + ',' + py[i].toFixed(2) + ',' + pp[i] + ',' + pt[i] + "\r\n";
		}
		return str;
	};

	this.UrlString = function() {
		var canvas1 = document.createElement('canvas');
		var px = data.x;
		var py = data.y;
		var pp = data.p;
		var pt = data.t;
		var count = px.length;
		if (count <= 0)
			return "";

		this.rect.left = Math.floor(px[0]);
		this.rect.right = Math.ceil(px[0]);
		this.rect.top = Math.floor(py[0]);
		this.rect.buttom = Math.ceil(py[0]);

		for (var i = 0; i < count; i++) {
			if (this.rect.left > px[i])
				this.rect.left = Math.floor(px[i]);
			if (this.rect.right < px[i])
				this.rect.right = Math.ceil(px[i]);
			if (this.rect.top > py[i])
				this.rect.top = Math.floor(py[i]);
			if (this.rect.buttom < py[i])
				this.rect.buttom = Math.ceil(py[i]);
		}
		//原始画布大小
		var ow = this.width;
		var oh = this.height;
		//数据宽度和高度
		var w = this.rect.right - this.rect.left;
		var h = this.rect.buttom - this.rect.top;
		//新画布大小
		var nw = w;
		var nh = h;
		//其实位置
		var sx, sy;
		//if(this.degree==0)
		{
			canvas1.width = w;
			canvas1.height = h;
			sx = this.rect.left;
			sy = this.rect.top;
		}
		//				else
		//				{
		//					canvas1.style.width=200;
		//					canvas1.style.height=200;
		//					sx=this.rect.left;
		//					sy=this.rect.top;
		//				}
		var context = canvas1.getContext("2d");		
		context.drawImage(canvas, sx - 2, sy - 2, nw + 4, nh + 4, 0, 0, nw, nh);
		context.save();		
		return canvas1.toDataURL();
	};

	//设置背景格式
	this.setLineStyle = function(style) {
		lineStyle = extend(lineStyle,style);
		
		
	}
	//设置线条格式
	this.setGridStyle= function(style) {
		gridStyle = extend(gridStyle,style);
		console.log(JSON.stringify(style));	
		
	}
	//设置点格式
	this.setPointStyle = function(style) {
		pointStyle = extend(pointStyle,style);
	}
	
	this.param=function(param){
		console.log(JSON.stringify(param));	
		this.setLineStyle(param.lineStyle);
		this.setGridStyle(param.gridStyle);
		this.setPointStyle(param.pointStyle);
		this.redraw(0);	
	}
	//得到数据
	this.getData = function() {
		return data;
	}
	function clear() {
		var w = this.width, h = this.height;
		ctx.clearRect(0, 0, w, h);		
		ctx.save();
		data.x = [];
		data.y = [];
		data.p = [];
		data.t = [];
		allPoint = [];
		data.count = 0;
		this.drawGrid();
	};

	function drawGrid() {
		//var ctx = this.ctx,
		var w = this.width, h = this.height, gridx = gridStyle.sw, gridy = gridStyle.sh;
		ctx.strokeStyle = gridStyle.color;
		ctx.lineJoin = gridStyle.mode;
		ctx.lineWidth = gridStyle.width;
				
		if(gridStyle&&(gridStyle.background!='#000'&&gridStyle.background!='#000000'))
		{
			ctx.fillStyle=gridStyle.background;
			ctx.fillRect(0, 0, w, h);
		}
		
		if (gridStyle.isShow) {			
			ctx.beginPath();
			var nH = parseInt(h / gridy);
			var sH = (h - nH * gridy) / 2;
			var nW = parseInt(w / gridx);
			var sW = (w - nW * gridx) / 2;
			for (var i = 0; i <= parseInt(h / gridy); i++) {
				ctx.moveTo(0, gridy * i + sH);
				ctx.lineTo(w, gridy * i + sH);
			}
			for (var i = 0; i <= parseInt(w / gridx); i++) {
				ctx.moveTo(gridx * i + sW, 0);
				ctx.lineTo(gridx * i + sW, h);
			}
			ctx.closePath();
			ctx.stroke();
		}
	};


	var jPoint = function(x1, y1, p1, t1) {
		this.x = x1;
		this.y = y1;
		this.p = p1 || 0;
		this.t = t1 || 0;
	};

	//重绘结果
	function redraw(inteval) {
		var w = this.width, h = this.height;
		
		ctx.clearRect(0, 0, w, h);
		if(gridStyle&&gridStyle.background!='#000'||gridStyle.background!='#000000')
		{
			ctx.fillStyle=gridStyle.background;
			ctx.fillRect(0, 0, w, h);
		}
		ctx.save();		
		this.drawGrid();
		drawSeg(0);		
		
		ctx.strokeStyle = lineStyle.color;//蓝色
		ctx.lineJoin = "round";
		ctx.lineWidth = lineStyle.width;
		ctx.linkColor=	lineStyle.color;	
		ctx.fillStyle = pointStyle.color;

		if (pointStyle.isInterpolation) {
			for (var i = 0; i < allPoint.length; i++) {
				ctx.fillStyle = lineStyle.color;
				ctx.beginPath();
				ctx.arc(allPoint[i].x, allPoint[i].y, 1, 0, pointStyle.r * Math.PI);
				ctx.closePath();
				ctx.fill();
			}
		}

		if (pointStyle.isShow) {
			ctx.fillStyle = pointStyle.color;
			for (var i = 0; i < data.count; i++) {
				ctx.beginPath();
				ctx.arc(data.x[i], data.y[i], 1, 0, pointStyle.r * Math.PI);
				ctx.closePath();
				ctx.fill();
			}
		}
		ctx.save();
	};


	function touchStart(event) {
		event.preventDefault();
		var count = data.count;		
		if (count == 0)
			ts = new Date();
		var tm = new Date();
		var tt = tm.getTime() - ts.getTime();
		if (!event.touches.length)
			return;
		var touch = event.touches[0];
		var px = data.x;
		var py = data.y;
		var pp = data.p;
		var pt = data.t;
		px.push(touch.pageX - offset.x);
		py.push(touch.pageY - offset.y);
		pp.push(1);
		pt.push(tt);
		data.count++;
		
		ctx.strokeStyle = lineStyle.color;//蓝色
		ctx.lineJoin = "round";
		ctx.lineWidth = lineStyle.width;
		ctx.linkColor=	lineStyle.color;	
		ctx.fillStyle = pointStyle.color;			
	};
	

	function touchMove(event) {
		event.preventDefault();
		if (!event.touches.length)
			return;

		var touch = event.touches[0];
		var tm = new Date();
		var w = this.width;
		var h = this.height;

		var px = data.x;
		var py = data.y;
		var pp = data.p;
		var pt = data.t;

		if (data.count == 0) {
			return;
		} else {
			//直接连线绘制曲线--第一种方式，暂时不用
			var oldx = px[px.length - 1];
			var oldy = py[py.length - 1];
			var oldp = pp[pp.length - 1];
			if (oldp != 0) {
				
				ctx.restore();
				ctx.beginPath();
				ctx.moveTo(oldx, oldy);
				ctx.lineTo(touch.pageX - offset.x, touch.pageY - offset.y);
				ctx.closePath();
				ctx.stroke();						
				if(pointStyle.isShow)
				{
					ctx.beginPath();
					ctx.arc(oldx, oldy,pointStyle.r, 0, 2 * Math.PI);
					ctx.closePath();
					ctx.fill();
				}						
			}
		};
		ctx.save();
		var tt = tm.getTime() - ts.getTime();
		px.push(touch.pageX - offset.x);
		py.push(touch.pageY - offset.y);
		pp.push(1);
		pt.push(tt);
		data.count++;
	}

	function touchEnd(event) {
		event.preventDefault();

		var tm = new Date();
		if (data.count == 0)
			ts = tm;
		var tt = tm.getTime() - ts.getTime();

		var px = data.x;
		var py = data.y;
		var pp = data.p;
		var pt = data.t;

		if (px.length <= 0)
			return;
		var x = px[px.length - 1];
		var y = py[py.length - 1];
		px.push(x);
		py.push(y);
		pp.push(0);
		pt.push(tt);

		data.count++;

		if (pointStyle.isShow) {
			ctx.beginPath();
			ctx.arc(x, y, pointStyle.r, 0, 2 * Math.PI);
			ctx.closePath();
			ctx.fill();
		}
		ctx.save();
	};
	
	function log(touch, tt) {
		console.log("No." + data.count + ",当前offx值为:" + parseInt(touch.pageX) + ", 当前offy值为:" + parseInt(touch.pageY) + "," + tt);
		//console.log("No."+data.count+",当前offx值为:" +parseInt(touch.clientX) + ", 当前offy值为:" + parseInt(touch.clientY)  + ","+tt);
		//console.log("No."+data.count+",当前offx值为:" +parseInt(touch.screenX) + ", 当前offy值为:" + parseInt(touch.screenY)  + ","+tt);
	};

	//分段差值重绘数据
	function drawSeg(start) {
	
		ctx.strokeStyle = lineStyle.color;//蓝色
		ctx.lineJoin = "round";
		ctx.lineWidth = lineStyle.width;
		ctx.linkColor=	lineStyle.color;	
		ctx.fillStyle = pointStyle.color;			
	
		allPoint = [];
		if (start < 0)
			start = 0;
		for (var k = 0; k < data.count; ) {
			var ParsplPoint = [];
			for (var i = k; i < data.count; i++) {
				if (data.p[i] != 0) {
					var point = new jPoint(data.x[i], data.y[i], data.p[i], data.t[i]);
					if (ParsplPoint.length == 0) {
						ParsplPoint.push(point);
					}
					ParsplPoint.push(point);
					k += 1;
				} else {
					var point = new jPoint(data.x[i], data.y[i], data.p[i], data.t[i]);
					ParsplPoint.push(point);
					k = i;
					break;
				}
			}
			k += 1;
			var point = ParsplPoint[ParsplPoint.length - 1];
			ParsplPoint.push(point);

			if (ParsplPoint.length < 4) {
				return;
			} else if (ParsplPoint.length == 2)//画直线
			{
				return;
			}
			ctx.restore();
			var i = 0, j = 0;
			var n = ParsplPoint.length - 1;
			var t1, t2, t3, t, a, b, c, d, x, y;
			var Clip = 10.0;
			t = 0.5 / Clip;

			ctx.beginPath();
			ctx.moveTo(ParsplPoint[1].x, ParsplPoint[1].y);

			for (var i = 0; i < n - 2; i++) {
				var curPoint = ParsplPoint[i + 1];
				var nextPoint = ParsplPoint[i + 2];
				allPoint.push(curPoint);
				var tt = curPoint.t;
				var te = nextPoint.t;

				Clip = (te - tt) / 1.0;
				t = 0.5 / Clip;

				for (var j = 1; j < Clip; j++) {
					t1 = j * t;
					t2 = t1 * t1;
					t3 = t2 * t1;
					a = 4.0 * t2 - t1 - 4.0 * t3;
					b = 1.0 - 10.0 * t2 + 12.0 * t3;
					c = t1 + 8.0 * t2 - 12.0 * t3;
					d = 4.0 * t3 - 2.0 * t2;
					x = a * ParsplPoint[i].x + b * ParsplPoint[i + 1].x + c * ParsplPoint[i + 2].x + d * ParsplPoint[i + 3].x;
					y = a * ParsplPoint[i].y + b * ParsplPoint[i + 1].y + c * ParsplPoint[i + 2].y + d * ParsplPoint[i + 3].y;
					ctx.lineTo(x, y);
					var tmp = tt + j * 1.0 / Clip;
					//console.log("tt="+tmp);
					var jp1 = new jPoint(x, y, 1, tt + j);
					allPoint.push(jp1);
				}
			}
			ctx.stroke();
			ctx.save();
		}

		//				for(var i=0;i<allPoint.length;i++)
		//				{
		//					ctx.fillStyle = "#3f4b96";
		//					ctx.beginPath();
		//	            	ctx.arc(allPoint[i].x,allPoint[i].y,2,0,2*Math.PI);
		//					ctx.closePath();
		//					ctx.fill();
		//				}
	};

	//差值数据结果
	function interpolation(inteval) {
		var w = this.width, h = this.height;
		ctx.clearRect(0, 0, w, h);
		this.drawGrid();
		drawSeg(0);		
		//return;		
		var ts1 = 0;
		ctx.fillStyle = pointStyle.color;
		ctx.strokeStyle = lineStyle.color;
		ctx.lineStyle = lineStyle.color;		
		ctx.lineJoin = "round";
		ctx.lineWidth = lineStyle.width;
		var str = "";
		for (var i = 0; i < allPoint.length; i++) {
			var tt = allPoint[i].t;
			if (tt >= ts1) {
				if(pointStyle.isShow)
				{
					ctx.beginPath();
					ctx.arc(allPoint[i].x, allPoint[i].y, pointStyle.r, 0, 2 * Math.PI);
					ctx.closePath();
					ctx.fill();
				}
				ts1 += inteval;				
				str += allPoint[i].x.toFixed(2) + "," + allPoint[i].y.toFixed(2) + "，" + allPoint[i].p + "," + allPoint[i].t.toFixed(0) + "\r\n";
			}
			if (tt > ts1 + inteval) 
				ts1 = tt + inteval;
		}			
		ctx.save();
		return str;
	};	
}
